<html>
<head><meta charset="utf-8"><title>Constructing ZSTs · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html">Constructing ZSTs</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="198585907"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198585907" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Diggsey <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198585907">(May 24 2020 at 14:38)</a>:</h4>
<p>Is it valid to call <code>mem::zeroed()</code> for ZSTs in general? What about the specific case of the empty tuple <code>()</code>?</p>



<a name="198586025"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586025" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586025">(May 24 2020 at 14:42)</a>:</h4>
<p>They have to be Copy.</p>
<p>Otherwise the type is allowed to control its creation and destruction as normal for any rust type.</p>



<a name="198586076"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586076" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586076">(May 24 2020 at 14:44)</a>:</h4>
<p>How does <code>Copy</code> relate to that? Something can be <code>Copy</code> and still have private fields</p>



<a name="198586084"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586084" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586084">(May 24 2020 at 14:44)</a>:</h4>
<p>The fields would also have to be Copy</p>



<a name="198586092"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586092" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586092">(May 24 2020 at 14:45)</a>:</h4>
<p>and a zst only has zst fields</p>



<a name="198586098"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586098" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586098">(May 24 2020 at 14:45)</a>:</h4>
<p>Sure, but why does that make it ok to construct the type from outside the containing module?</p>



<a name="198586160"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586160" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586160">(May 24 2020 at 14:46)</a>:</h4>
<p>Constructing a ZST via <code>mem::zeroed()</code> is not UB from what I understand, but if you don't control the ZST you can break arbitrary library invariants and cause UB that way</p>



<a name="198586167"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586167" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586167">(May 24 2020 at 14:47)</a>:</h4>
<p>Well I suppose you <em>could</em> construct a counter-example but once the type is Copy I can't imagine what that counter-example could be</p>



<a name="198586223"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586223" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586223">(May 24 2020 at 14:49)</a>:</h4>
<p>I'm not sure what you mean</p>



<a name="198586230"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586230" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586230">(May 24 2020 at 14:49)</a>:</h4>
<p><code>bare_metal::CriticalSection</code> for example is <code>Copy</code> <a href="https://github.com/rust-embedded/bare-metal/blob/e2689eabf6c9c86ff9f02512d506251716d0b6af/src/lib.rs#L15-L18">https://github.com/rust-embedded/bare-metal/blob/e2689eabf6c9c86ff9f02512d506251716d0b6af/src/lib.rs#L15-L18</a></p>



<a name="198586234"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586234" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586234">(May 24 2020 at 14:49)</a>:</h4>
<p>But creating it is unsafe and must only be done when no preemption is possible</p>



<a name="198586286"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586286" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586286">(May 24 2020 at 14:50)</a>:</h4>
<p>Interesting.</p>



<a name="198586343"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586343" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586343">(May 24 2020 at 14:52)</a>:</h4>
<p>So the count is unimportant, only that some initialization occurred</p>



<a name="198586347"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586347" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586347">(May 24 2020 at 14:52)</a>:</h4>
<p>confounding</p>



<a name="198586409"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586409" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586409">(May 24 2020 at 14:54)</a>:</h4>
<p>Yeah, and in this case the lifetime is important as well</p>



<a name="198586416"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586416" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586416">(May 24 2020 at 14:54)</a>:</h4>
<p>In other embedded use cases you might have a ZST token without lifetimes to indicate that some initialization occurred (eg. an external clock is started)</p>



<a name="198586499"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586499" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586499">(May 24 2020 at 14:56)</a>:</h4>
<p>I should have thought of this already because this is actually a thing needed for some SIMD setups as well</p>



<a name="198586878"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586878" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586878">(May 24 2020 at 15:05)</a>:</h4>
<p><span class="user-mention silent" data-user-id="295632">Diggory Blake</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Constructing.20ZSTs/near/198585907">said</a>:</p>
<blockquote>
<p>Is it valid to call <code>mem::zeroed()</code> for ZSTs in general? What about the specific case of the empty tuple <code>()</code>?</p>
</blockquote>
<p>No. This is not valid for <code>!</code>.</p>



<a name="198586884"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586884" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586884">(May 24 2020 at 15:05)</a>:</h4>
<p>And <code>!</code> is also <code>Copy</code> so that bound doesn't help either.</p>



<a name="198586955"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586955" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586955">(May 24 2020 at 15:06)</a>:</h4>
<p>For the 0-ary tuple <code>()</code>, since it is inhabited <em>and</em> <code>Copy</code>, then yes <code>mem::zeroed()</code> is valid. So is <code>mem::uninitialized()</code>. These two functions are actually equivalent for ZSTs.</p>



<a name="198586965"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198586965" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198586965">(May 24 2020 at 15:07)</a>:</h4>
<p>(I am avoiding "empty tuple" because "empty type" is a technical term in type theory and it refers to <code>!</code>, not <code>()</code>.)</p>



<a name="198596978"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198596978" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> isHavvy <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198596978">(May 24 2020 at 19:47)</a>:</h4>
<p>field-less tuple</p>



<a name="198597318"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198597318" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198597318">(May 24 2020 at 19:55)</a>:</h4>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Constructing.20ZSTs/near/198586167">said</a>:</p>
<blockquote>
<p>Well I suppose you <em>could</em> construct a counter-example but once the type is Copy I can't imagine what that counter-example could be</p>
</blockquote>
<p>(already mentioned above, just repeating for clarity) there actually is a very simple counterexample, and it's <code>!</code>.</p>



<a name="198709244"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198709244" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198709244">(May 25 2020 at 23:44)</a>:</h4>
<p><a href="https://github.com/chorman0773/SNES-Dev/blob/e1b6989fd5a378244279c70cf82cf1e8352cbb1e/rust-api/src/lib.rs#L13">https://github.com/chorman0773/SNES-Dev/blob/e1b6989fd5a378244279c70cf82cf1e8352cbb1e/rust-api/src/lib.rs#L13</a> mem::zeroed() this, I dare you.</p>



<a name="198711911"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198711911" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198711911">(May 26 2020 at 00:52)</a>:</h4>
<p>that does not even fit my initial invalid criteria</p>



<a name="198716063"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198716063" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198716063">(May 26 2020 at 02:48)</a>:</h4>
<p>A more serious example would be a type with a bounded lifetime that exists as a promise of some state for that lifetime. If there is only one possible state to promise, that could easily be a ZST, and even be T: Copy.</p>



<a name="198717188"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing%20ZSTs/near/198717188" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Constructing.20ZSTs.html#198717188">(May 26 2020 at 03:18)</a>:</h4>
<p>Yes that was the basic idea of the bare_metal example. Some people also plan to do that with CPU features.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>